ld -r
Paul Edwards
mutazilah@gmail.com
Sun Apr 25 15:04:17 GMT 2021
I've got a fix for the undefined symbols.
BFN. Paul.
C:\devel\binutils-2.14a\bfd>cvs diff -c -r stage22 -l
cvs diff: Diffing .
Index: aoutx.h
===================================================================
RCS file: c:\cvsroot/binutils-2.14a/bfd/aoutx.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** aoutx.h 25 Apr 2021 11:06:39 -0000 1.2
--- aoutx.h 25 Apr 2021 14:56:14 -0000 1.3
***************
*** 4984,4989 ****
--- 4984,4998 ----
{
if (h != NULL)
{
+ #ifdef PUREISO
+ const char *name;
+
+ name = h->root.root.string;
+ if (! ((*finfo->info->callbacks->undefined_symbol)
+ (finfo->info, name, input_bfd, input_section,
+ r_addr, TRUE)))
+ return FALSE;
+ #endif
/* We decided to strip this symbol, but it
turns out that we can't. Note that we
lose the other and desc information here.
-----Original Message-----
From: Paul Edwards
Sent: Sunday, April 25, 2021 10:42 PM
To: binutils@sourceware.org ; Nick Clifton
Subject: Re: ld -r
I had a breakthrough with this problem with
binutils 2.14a.
I found this:
https://insights.sei.cmu.edu/blog/when-aslr-is-not-really-aslr-the-case-of-incorrect-assumptions-and-bad-defaults/
While testing a simple "Hello world" application produced with mingw-w64,
the addition of the following line before the main function resulted in an
executable file that retained its relocation table:
__declspec(dllexport)
Which I tried out on my mainCRTStartup and suddenly
I started getting relocations for my Windows executables!
Now that I had something to compare, I could compare
good and bad logic flow in binutils and found that there
is a specific test:
/* If we are not building a DLL, when there are no exports
we do not build an export table at all. */
if (!pe_dll_export_everything && pe_def_file->num_exports == 0
&& !(info->shared))
return;
which prevents a relocation section from being generated.
That doesn't look correct to me. Aren't these independent
things? ie exports versus relocation.
Regardless, as per below patch, I masked that logic
out (don't worry about the name "PUREISO", that's
just what I've been using for all my changes), and
everything worked fine.
I thought this might fix the similar problem with
producing a.out modules, but the code responsible
for that:
if (info->relocateable)
seems to be a different issue. It seems to me that
relocateable should be a default and only if you
want to strip relocations should that be set to 0.
Regardless, I just got it to ignore that flag in
certain circumstances and was successful in
getting relocations output.
Although it's still not reporting unresolved externals
so I'll probably change it to force that to be 1 after all.
BFN. Paul.
Index: bfd/aoutx.h
===================================================================
RCS file: c:\cvsroot/binutils-2.14a/bfd/aoutx.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** bfd/aoutx.h 21 Jun 2018 02:35:38 -0000 1.1.1.1
--- bfd/aoutx.h 25 Apr 2021 11:06:39 -0000 1.2
***************
*** 3759,3765 ****
{
bfd_size_type sz;
! if (info->relocateable)
{
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
{
--- 3759,3765 ----
{
bfd_size_type sz;
! if (PUREISO || info->relocateable)
{
if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
{
***************
*** 3803,3809 ****
}
}
! if (info->relocateable)
{
if (obj_textsec (abfd) != (asection *) NULL)
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
--- 3803,3809 ----
}
}
! if (PUREISO || info->relocateable)
{
if (obj_textsec (abfd) != (asection *) NULL)
trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
***************
*** 4788,4794 ****
/* If we are producing relocateable output, the relocs were
modified, and we now write them out. */
! if (finfo->info->relocateable && rel_size > 0)
{
if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
return FALSE;
--- 4788,4794 ----
/* If we are producing relocateable output, the relocs were
modified, and we now write them out. */
! if ((PUREISO || finfo->info->relocateable) && rel_size > 0)
{
if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
return FALSE;
***************
*** 4935,4941 ****
}
#endif
! if (relocateable)
{
/* We are generating a relocateable output file, and must
modify the reloc accordingly. */
--- 4935,4941 ----
}
#endif
! if (PUREISO || relocateable)
{
/* We are generating a relocateable output file, and must
modify the reloc accordingly. */
***************
*** 5256,5262 ****
BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
! if (relocateable)
{
/* We are generating a relocateable output file, and must
modify the reloc accordingly. */
--- 5256,5262 ----
BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
! if (PUREISO || relocateable)
{
/* We are generating a relocateable output file, and must
modify the reloc accordingly. */
Index: ld/pe-dll.c
===================================================================
RCS file: c:\cvsroot/binutils-2.14a/ld/pe-dll.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** ld/pe-dll.c 21 Jun 2018 02:36:35 -0000 1.1.1.1
--- ld/pe-dll.c 25 Apr 2021 11:10:05 -0000 1.2
***************
*** 564,574 ****
--- 564,576 ----
}
}
+ #ifndef PUREISO
/* If we are not building a DLL, when there are no exports
we do not build an export table at all. */
if (!pe_dll_export_everything && pe_def_file->num_exports == 0
&& !(info->shared))
return;
+ #endif
/* Now, maybe export everything else the default way. */
if (pe_dll_export_everything || pe_def_file->num_exports == 0)
***************
*** 2672,2679 ****
--- 2674,2683 ----
pe_dll_id_target (bfd_get_target (abfd));
process_def_file (abfd, info);
+ #ifndef PUREISO
if (pe_def_file->num_exports == 0 && !(info->shared))
return;
+ #endif
generate_edata (abfd, info);
build_filler_bfd (1);
-----Original Message-----
From: Paul Edwards
Sent: Friday, April 9, 2021 11:34 AM
To: binutils@sourceware.org ; Nick Clifton
Subject: Re: ld -r
Hi Nick.
Thanks for your reply. Sorry about the delay.
My actual use is a customized GCC 3.2.3 and a
customized binutils 2.14a.
I can't use pie:
gcc386 -fpie -S -Os -fno-common -D__PDOS386__ -D__32BIT__ -I. -I../src -o
pdptest.s pdptest.c
pdptest.c:0: unrecognized option `-fpie'
I can't really use pic:
gcc386 -fpic -S -Os -fno-common -D__PDOS386__ -D__32BIT__ -I. -I../src -o
pdptest.s pdptest.c
as386 -o pdptest.o pdptest.s
...
pdptest.s:73: Error: cannot represent relocation type BFD_RELOC_386_GOTOFF
pdptest.s:78: Error: cannot represent relocation type BFD_RELOC_386_PLT32
And even if that did work, I don't think that's what I want.
Actually ld386 -r gives me exactly what I want, an O_MAGIC
a.out file. The only problems are:
1. No reporting of undefined symbols (I can work around
this by doing two links, the first without "-r" to report
the undefined symbols, before my real link).
2. The executable is a bit larger than I expected. Maybe
20% or so. But that may be due to "ident" strings, I'm
not sure. And either way, I can work around the problem
by just ignoring it.
3. I need t run a separate "strip" command to delete
some stuff I don't want, ie:
strip386 --strip-unneeded pdptest.exe
I know that the .o and .a files I am currently producing are
good enough to do the job, because I'm already using them
successfully. The information required to produce the a.out
file I want is already there. I just want ld386, maybe in
combination with something else, to produce the executable,
reporting unresolved errors, and of the proper size, and
preferably stripped.
Today I saw there was a "-N" option which looked promising,
but for some reason it set the text relocations and data
relocations to 0 (see offset 0x18 and 0x1c). Adding "-q"
didn't help either.
ld386 -N -s -e ___pdosst32 -o pdptest.exe pdosst32.o pdptest.o pdos.a
C:\devel\pdos\pdpclib>hexdump pdptest.exe 0 50
000000 07016400 086B0000 F8060000 B0670000 ..d..k.......g..
000010 00000000 00000000 00000000 00000000 ................
Note that without "-N" it produces N_MAGIC, which
is not what I want.
Here is what a good executable looks like, and you
can see there is data in 0x18 and 0x1c:
ld386 -s -e ___pdosst32 -o pdptest.exe pdosst32.o pdptest.o pdos.a
ld386 -r -s -e ___pdosst32 -o pdptest.exe pdosst32.o pdptest.o pdos.a
strip386 --strip-unneeded pdptest.exe
C:\devel\pdos\pdpclib>hexdump pdptest.exe 0 50
000000 07016400 086B0000 F8060000 B0670000 ..d..k.......g..
000010 00000000 00000000 50120000 70000000 ........P...p...
Note that a.out is the format I have been producing
for something like 25 years, using EMX 0.9d. But I
have switched to my own builds running under
Windows a few years ago.
If there is no option to "ld" in binutils 2.14a to do what
I want, is there something I can change in the binutils
2.14a source code to make "ld" report unresolved
externals when "-r" is used?
Or to fill in the text and data relocations when "-N" is used?
Thanks. Paul.
-----Original Message-----
From: Nick Clifton
Sent: Monday, May 11, 2020 9:35 PM
To: Paul Edwards ; binutils@sourceware.org
Subject: Re: ld -r
Hi Paul,
> Why does adding "-r" to "ld" allow the link
> to complete without error, even when there
> are undefined symbols?
Because the "-r" option tells the linker to perform a partial
link, not a full link. It combines together the input files
into a single output file, but this output is not a functioning
binary yet. It still needs a final link, which includes references
to the appropriate libraries and other object files, in order
for an executable to be produced.
> Is there an option I
> can use to get the link to fail as expected?
Just do not use the "-r" option.
> Note that I am using "-r" to produce
> relocatable executables. See below for example.
Unfortunately that is not the purpose of this option.
If you do not need to control the linker directly then using gcc to
perform the compilation and link is a much easier way to go. For
example:
gcc -fpic main.c
Note that you usually need to provide an option to gcc to tell it
that you want to produce a relocatable executable. In the above
example -fpic is used.
If you do need to control the linker directly then normally no
special options are needed to make a relocatable executable.
Provided that you have compiled the code with the -fpic or -fpie
options then a relocatable program should be produced. If you
are trying to build a relocatable library however then you do
need to give the linker the "-shared" command line option.
Cheers
Nick
More information about the Binutils
mailing list