diff options
-rw-r--r-- | debian/changelog | 3 | ||||
-rw-r--r-- | scripts/Dpkg/Shlibs/Objdump.pm | 12 | ||||
-rw-r--r-- | scripts/Makefile.am | 23 | ||||
-rw-r--r-- | scripts/t/Dpkg_Shlibs.t | 38 | ||||
-rw-r--r-- | scripts/t/Dpkg_Shlibs/.gitignore | 1 | ||||
-rw-r--r-- | scripts/t/Dpkg_Shlibs/objdump.spacesyms | 124 | ||||
-rwxr-xr-x | scripts/t/Dpkg_Shlibs/spacesyms-c-gen.pl | 37 | ||||
-rwxr-xr-x | scripts/t/Dpkg_Shlibs/spacesyms-o-map.pl | 25 | ||||
-rw-r--r-- | scripts/t/Dpkg_Shlibs/spacesyms.map | 7 |
9 files changed, 262 insertions, 8 deletions
diff --git a/debian/changelog b/debian/changelog index fbc0f6cad..6104c4ebd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -65,6 +65,9 @@ dpkg (1.18.2) UNRELEASED; urgency=low - Make the dependency comparison deep by comparing not only the first dependency alternative, to get them sorted in a reproducible way. Based on a patch by Chris Lamb <lamby@debian.org>. Closes: #792491 + - Support spaces in symbol names in Dpkg::Shlibs::Objdump. This is + required by Go shared libraries. Closes: #785344 + Based on a patch by Michael Hudson-Doyle <michael.hudson@canonical.com>. * Test suite: - Set SIGINT, SIGTERM and SIGPIPE to their default actions to get deterministic behavior. diff --git a/scripts/Dpkg/Shlibs/Objdump.pm b/scripts/Dpkg/Shlibs/Objdump.pm index c19c3fbd7..0addecbdd 100644 --- a/scripts/Dpkg/Shlibs/Objdump.pm +++ b/scripts/Dpkg/Shlibs/Objdump.pm @@ -194,8 +194,8 @@ sub parse_objdump_output { my $section = 'none'; while (<$fh>) { - chomp; - next if /^\s*$/; + s/\s*$//; + next if length == 0; if (/^DYNAMIC SYMBOL TABLE:/) { $section = 'dynsym'; @@ -221,7 +221,7 @@ sub parse_objdump_output { if ($section eq 'dynsym') { $self->parse_dynamic_symbol($_); } elsif ($section eq 'dynreloc') { - if (/^\S+\s+(\S+)\s+(\S+)\s*$/) { + if (/^\S+\s+(\S+)\s+(.+)$/) { $self->{dynrelocs}{$2} = $1; } else { warning(g_("couldn't parse dynamic relocation record: %s"), $_); @@ -248,9 +248,9 @@ sub parse_objdump_output { } } } elsif ($section eq 'none') { - if (/^\s*.+:\s*file\s+format\s+(\S+)\s*$/) { + if (/^\s*.+:\s*file\s+format\s+(\S+)$/) { $self->{format} = $1; - } elsif (/^architecture:\s*\S+,\s*flags\s*\S+:\s*$/) { + } elsif (/^architecture:\s*\S+,\s*flags\s*\S+:$/) { # Parse 2 lines of "-f" # architecture: i386, flags 0x00000112: # EXEC_P, HAS_SYMS, D_PAGED @@ -299,7 +299,7 @@ sub parse_objdump_output { sub parse_dynamic_symbol { my ($self, $line) = @_; my $vis_re = '(\.protected|\.hidden|\.internal|0x\S+)'; - if ($line =~ /^[0-9a-f]+ (.{7})\s+(\S+)\s+[0-9a-f]+(?:\s+(\S+))?(?:\s+$vis_re)?\s+(\S+)/) { + if ($line =~ /^[0-9a-f]+ (.{7})\s+(\S+)\s+[0-9a-f]+(?:\s+(\S+))?(?:\s+$vis_re)?\s+(.+)/) { my ($flags, $sect, $ver, $vis, $name) = ($1, $2, $3, $4, $5); diff --git a/scripts/Makefile.am b/scripts/Makefile.am index afb9b1448..a55ffad77 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -255,6 +255,7 @@ test_data = \ t/Dpkg_Shlibs/ld.so.conf.d/inf_recurse.conf \ t/Dpkg_Shlibs/ld.so.conf.d/recursive.conf \ t/Dpkg_Shlibs/objdump.space \ + t/Dpkg_Shlibs/objdump.spacesyms \ t/Dpkg_Shlibs/objdump.basictags-amd64 \ t/Dpkg_Shlibs/objdump.basictags-i386 \ t/Dpkg_Shlibs/objdump.basictags-mips \ @@ -265,6 +266,9 @@ test_data = \ t/Dpkg_Shlibs/objdump.libc6-2.6 \ t/Dpkg_Shlibs/objdump.dbd-pg \ t/Dpkg_Shlibs/objdump.ls \ + t/Dpkg_Shlibs/spacesyms.map \ + t/Dpkg_Shlibs/spacesyms-c-gen.pl \ + t/Dpkg_Shlibs/spacesyms-o-map.pl \ t/Dpkg_Source_Patch/c-style.patch \ t/Dpkg_Source_Patch/ghost-hunk.patch \ t/Dpkg_Source_Patch/index-+++.patch \ @@ -314,7 +318,9 @@ test_data_objects = \ t/Dpkg_Shlibs/libobjdump.basictags-amd64.so \ t/Dpkg_Shlibs/libobjdump.basictags-i386.so \ t/Dpkg_Shlibs/libobjdump.basictags-mips.so \ - t/Dpkg_Shlibs/libobjdump.patterns.so + t/Dpkg_Shlibs/libobjdump.patterns.so \ + t/Dpkg_Shlibs/libobjdump.spacesyms.so \ + $(nil) $(srcdir)/t/Dpkg_Shlibs/libobjdump.basictags-amd64.so: $(srcdir)/t/Dpkg_Shlibs/basictags.c $(CC) $(CFLAGS) -shared -fPIC -Wl,-soname -Wl,libbasictags.so.1 $< \ @@ -333,6 +339,19 @@ $(srcdir)/t/Dpkg_Shlibs/libobjdump.patterns.so: $(srcdir)/t/Dpkg_Shlibs/patterns -Wl,--version-script=$(srcdir)/t/Dpkg_Shlibs/patterns.map $< \ -o $@ +$(srcdir)/t/Dpkg_Shlibs/spacesyms.c: $(srcdir)/t/Dpkg_Shlibs/spacesyms-c-gen.pl + $(srcdir)/t/Dpkg_Shlibs/spacesyms-c-gen.pl > $@ + +$(srcdir)/t/Dpkg_Shlibs/spacesyms.o: $(srcdir)/t/Dpkg_Shlibs/spacesyms.c $(srcdir)/t/Dpkg_Shlibs/spacesyms-o-map.pl + $(CC) $(CFLAGS) -c -fPIC -o $@.tmp $< + $(srcdir)/t/Dpkg_Shlibs/spacesyms-o-map.pl $@.tmp $@ + rm -f $@.tmp + +$(srcdir)/t/Dpkg_Shlibs/libobjdump.spacesyms.so: $(srcdir)/t/Dpkg_Shlibs/spacesyms.o $(srcdir)/t/Dpkg_Shlibs/spacesyms.map + $(CC) -shared -Wl,-soname -Wl,libspacesyms.so.1 \ + -Wl,--version-script=$(srcdir)/t/Dpkg_Shlibs/spacesyms.map $< \ + -o $@ + .PHONY: refresh-test-data OBJDUMP = objdump -w -f -p -T -R @@ -346,6 +365,8 @@ refresh-test-data: $(test_data_objects) >$(srcdir)/t/Dpkg_Shlibs/objdump.basictags-mips $(OBJDUMP) $(srcdir)/t/Dpkg_Shlibs/libobjdump.patterns.so \ >$(srcdir)/t/Dpkg_Shlibs/objdump.patterns + $(OBJDUMP) $(srcdir)/t/Dpkg_Shlibs/libobjdump.spacesyms.so \ + >$(srcdir)/t/Dpkg_Shlibs/objdump.spacesyms $(OBJDUMP) `which ls` >$(srcdir)/t/Dpkg_Shlibs/objdump.ls include $(top_srcdir)/check.am diff --git a/scripts/t/Dpkg_Shlibs.t b/scripts/t/Dpkg_Shlibs.t index 4bcd848c5..cfe3c5db5 100644 --- a/scripts/t/Dpkg_Shlibs.t +++ b/scripts/t/Dpkg_Shlibs.t @@ -16,7 +16,7 @@ use strict; use warnings; -use Test::More tests => 124; +use Test::More tests => 148; use Cwd; use IO::String; @@ -351,6 +351,42 @@ is_deeply( $sym, { name => 'IA__g_free', version => '', hidden => '', defined => 1 }, 'symbol with visibility without version' ); +# Check parsing of objdump output when symbol names contain spaces +$obj = Dpkg::Shlibs::Objdump::Object->new; + +open $objdump, '<', "$datadir/objdump.spacesyms" + or die "$datadir/objdump.spacesyms: $!"; +$obj->parse_objdump_output($objdump); +close $objdump; + +sub check_spacesym { + my ($name, $version, $visibility) = @_; + + $visibility //= ''; + $sym = $obj->get_symbol($name . "@" . $version); + is_deeply($sym, { name => $name, version => $version, + soname => 'libspacesyms.so.1', + objid => 'libspacesyms.so.1', + section => '.text', dynamic => 1, + debug => '', type => 'F', weak => '', + local => '', global => 1, visibility => $visibility, + hidden => '', defined => 1 }, $name); + ok(defined $obj->{dynrelocs}{$name}, "dynreloc found for $name"); +} + +check_spacesym('symdefaultvernospacedefault', 'Base'); +check_spacesym('symdefaultvernospaceprotected', 'Base', 'protected'); +check_spacesym('symlongvernospacedefault', 'VERY_LONG_VERSION_1'); +check_spacesym('symlongvernospaceprotected', 'VERY_LONG_VERSION_1', 'protected'); +check_spacesym('symshortvernospacedefault', 'V1'); +check_spacesym('symshortvernospaceprotected', 'V1', 'protected'); +check_spacesym('symdefaultverSPA CEdefault', 'Base'); +check_spacesym('symdefaultverSPA CEprotected', 'Base', 'protected'); +check_spacesym('symlongverSPA CEdefault', 'VERY_LONG_VERSION_1'); +check_spacesym('symlongverSPA CEprotected', 'VERY_LONG_VERSION_1', 'protected'); +check_spacesym('symshortverSPA CEdefault', 'V1'); +check_spacesym('symshortverSPA CEprotected', 'V1', 'protected'); + ####### Test symbol tagging support ###### # Parsing/dumping diff --git a/scripts/t/Dpkg_Shlibs/.gitignore b/scripts/t/Dpkg_Shlibs/.gitignore new file mode 100644 index 000000000..2bfb8152d --- /dev/null +++ b/scripts/t/Dpkg_Shlibs/.gitignore @@ -0,0 +1 @@ +spacesyms.c diff --git a/scripts/t/Dpkg_Shlibs/objdump.spacesyms b/scripts/t/Dpkg_Shlibs/objdump.spacesyms new file mode 100644 index 000000000..f307ee5a5 --- /dev/null +++ b/scripts/t/Dpkg_Shlibs/objdump.spacesyms @@ -0,0 +1,124 @@ + +./t/Dpkg_Shlibs/libobjdump.spacesyms.so: file format elf32-i386 +architecture: i386, flags 0x00000150: +HAS_SYMS, DYNAMIC, D_PAGED +start address 0x000007a0 + +Program Header: + LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**12 + filesz 0x00000d5c memsz 0x00000d5c flags r-x + LOAD off 0x00000d5c vaddr 0x00001d5c paddr 0x00001d5c align 2**12 + filesz 0x00000204 memsz 0x00000208 flags rw- + DYNAMIC off 0x00000d68 vaddr 0x00001d68 paddr 0x00001d68 align 2**2 + filesz 0x000000f8 memsz 0x000000f8 flags rw- + NOTE off 0x000000f4 vaddr 0x000000f4 paddr 0x000000f4 align 2**2 + filesz 0x00000024 memsz 0x00000024 flags r-- +EH_FRAME off 0x00000a68 vaddr 0x00000a68 paddr 0x00000a68 align 2**2 + filesz 0x000000d4 memsz 0x000000d4 flags r-- + STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4 + filesz 0x00000000 memsz 0x00000000 flags rw- + +Dynamic Section: + NEEDED libc.so.6 + SONAME libspacesyms.so.1 + INIT 0x00000740 + FINI 0x00000a54 + INIT_ARRAY 0x00001d5c + INIT_ARRAYSZ 0x00000004 + FINI_ARRAY 0x00001d60 + FINI_ARRAYSZ 0x00000004 + GNU_HASH 0x00000118 + STRTAB 0x0000036c + SYMTAB 0x000001cc + STRSZ 0x00000214 + SYMENT 0x00000010 + PLTGOT 0x00001e74 + PLTRELSZ 0x00000010 + PLTREL 0x00000011 + JMPREL 0x00000730 + REL 0x00000630 + RELSZ 0x00000100 + RELENT 0x00000008 + VERDEF 0x000005b4 + VERDEFNUM 0x00000003 + VERNEED 0x00000610 + VERNEEDNUM 0x00000001 + VERSYM 0x00000580 + RELCOUNT 0x0000000f + +Version definitions: +1 0x01 0x026eb371 libspacesyms.so.1 +2 0x00 0x00000591 V1 +3 0x00 0x0df29ee1 VERY_LONG_VERSION_1 + V1 + +Version References: + required from libc.so.6: + 0x09691f73 0x00 04 GLIBC_2.1.3 + +DYNAMIC SYMBOL TABLE: +00000000 w D *UND* 00000000 _ITM_deregisterTMCloneTable +00000000 w DF *UND* 00000000 GLIBC_2.1.3 __cxa_finalize +00000000 w D *UND* 00000000 __gmon_start__ +00000000 w D *UND* 00000000 _Jv_RegisterClasses +00000000 w D *UND* 00000000 _ITM_registerTMCloneTable +00000920 g DF .text 00000002 Base symdefaultverSPA CEdefault +00000a54 g DF .fini 00000000 Base _fini +00001f00 g DO .data 00000060 Base funcs +00000740 g DF .init 00000000 Base _init +000009e0 g DF .text 00000002 V1 symshortvernospacedefault +00001f60 g D .bss 00000000 Base __bss_start +00000900 g DF .text 00000002 Base .protected symdefaultvernospaceprotected +00001f64 g D .bss 00000000 Base _end +00000a20 g DF .text 00000002 V1 symshortverSPA CEdefault +00000000 g DO *ABS* 00000000 V1 V1 +00000a00 g DF .text 00000002 V1 .protected symshortvernospaceprotected +00000960 g DF .text 00000002 VERY_LONG_VERSION_1 symlongvernospacedefault +00000000 g DO *ABS* 00000000 VERY_LONG_VERSION_1 VERY_LONG_VERSION_1 +00001f60 g D .data 00000000 Base _edata +000008e0 g DF .text 00000002 Base symdefaultvernospacedefault +000009c0 g DF .text 00000002 VERY_LONG_VERSION_1 .protected symlongverSPA CEprotected +00000940 g DF .text 00000002 Base .protected symdefaultverSPA CEprotected +000009a0 g DF .text 00000002 VERY_LONG_VERSION_1 symlongverSPA CEdefault +00000a40 g DF .text 00000002 V1 .protected symshortverSPA CEprotected +00000980 g DF .text 00000002 VERY_LONG_VERSION_1 .protected symlongvernospaceprotected + + +DYNAMIC RELOCATION RECORDS +OFFSET TYPE VALUE +00001d5c R_386_RELATIVE *ABS* +00001d60 R_386_RELATIVE *ABS* +00001ec0 R_386_RELATIVE *ABS* +00001f04 R_386_RELATIVE *ABS* +00001f0c R_386_RELATIVE *ABS* +00001f14 R_386_RELATIVE *ABS* +00001f1c R_386_RELATIVE *ABS* +00001f24 R_386_RELATIVE *ABS* +00001f2c R_386_RELATIVE *ABS* +00001f34 R_386_RELATIVE *ABS* +00001f3c R_386_RELATIVE *ABS* +00001f44 R_386_RELATIVE *ABS* +00001f4c R_386_RELATIVE *ABS* +00001f54 R_386_RELATIVE *ABS* +00001f5c R_386_RELATIVE *ABS* +00001e60 R_386_GLOB_DAT _ITM_deregisterTMCloneTable +00001e64 R_386_GLOB_DAT __cxa_finalize +00001e68 R_386_GLOB_DAT __gmon_start__ +00001e6c R_386_GLOB_DAT _Jv_RegisterClasses +00001e70 R_386_GLOB_DAT _ITM_registerTMCloneTable +00001f00 R_386_32 symdefaultvernospacedefault +00001f08 R_386_32 symdefaultvernospaceprotected +00001f10 R_386_32 symdefaultverSPA CEdefault +00001f18 R_386_32 symdefaultverSPA CEprotected +00001f20 R_386_32 symlongvernospacedefault +00001f28 R_386_32 symlongvernospaceprotected +00001f30 R_386_32 symlongverSPA CEdefault +00001f38 R_386_32 symlongverSPA CEprotected +00001f40 R_386_32 symshortvernospacedefault +00001f48 R_386_32 symshortvernospaceprotected +00001f50 R_386_32 symshortverSPA CEdefault +00001f58 R_386_32 symshortverSPA CEprotected +00001e80 R_386_JUMP_SLOT __cxa_finalize +00001e84 R_386_JUMP_SLOT __gmon_start__ + + diff --git a/scripts/t/Dpkg_Shlibs/spacesyms-c-gen.pl b/scripts/t/Dpkg_Shlibs/spacesyms-c-gen.pl new file mode 100755 index 000000000..48434f45d --- /dev/null +++ b/scripts/t/Dpkg_Shlibs/spacesyms-c-gen.pl @@ -0,0 +1,37 @@ +#!/usr/bin/perl +# +# spacesyms-c-gen.pl +# +# Output a C file that contains symbols matching the shell glob +# sym{defaultver,longver,shortver}{nospace,SPACE}{default,hidden,protected,internal} +# with symbol visibility matching the final element and at least one relocation +# against each symbol. +# +# When used together with spacesyms-o-map.pl and spacesyms.map, makes a shared +# object that contains symbols that covers all cases of: +# +# 1) has a short, long or Base version, +# 2) has or does not have a space in the symbol name, +# 3) default, hidden, protected or internal visibility. + +use strict; +use warnings; + +my @symbols; + +foreach my $version (qw(defaultver longver shortver)) { + foreach my $space (qw(nospace SPACE)) { + foreach my $visibility (qw(default hidden protected internal)) { + my $symbol = "sym$version$space$visibility"; + push @symbols, $symbol; + print "void $symbol(void) __attribute__((visibility(\"$visibility\")));\n"; + print "void $symbol(void) {}\n"; + } + } +} + +print "void (*funcs[])(void) = {\n"; +foreach my $symbol (@symbols) { + print "$symbol,\n"; +} +print "};\n"; diff --git a/scripts/t/Dpkg_Shlibs/spacesyms-o-map.pl b/scripts/t/Dpkg_Shlibs/spacesyms-o-map.pl new file mode 100755 index 000000000..89a1caf71 --- /dev/null +++ b/scripts/t/Dpkg_Shlibs/spacesyms-o-map.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +# +# spacesyms-o-map.pl INPUT OUTPUT +# +# Copy the object file INPUT to OUTPUT, redefining any symbol in INPUT that +# contains "SPACE" in its name to contain "SPA CE" instead. + +use strict; +use warnings; + +my ($input, $output) = @ARGV; +my @cmds = ('objcopy'); + +open my $nm, '-|', 'nm', $input or die "cannot run nm: $!"; +while (<$nm>) { + next if not m/SPACE/; + chomp; + my $x = (split / /, $_, 3)[2]; + my $y = $x =~ s/SPACE/SPA CE/r; + push @cmds, "--redefine-sym=$x=$y"; +} +close $nm; + +push @cmds, $input, $output; +exec @cmds; diff --git a/scripts/t/Dpkg_Shlibs/spacesyms.map b/scripts/t/Dpkg_Shlibs/spacesyms.map new file mode 100644 index 000000000..005344623 --- /dev/null +++ b/scripts/t/Dpkg_Shlibs/spacesyms.map @@ -0,0 +1,7 @@ +V1 { + global: symshortver*; +}; + +VERY_LONG_VERSION_1 { + global: symlongver*; +} V1; |