diff --git a/util/led/finish.c b/util/led/finish.c index 12daa31a9..cc0817698 100644 --- a/util/led/finish.c +++ b/util/led/finish.c @@ -119,7 +119,7 @@ handle_relos(head, sects, names) * Write out the (probably changed) * relocation information. */ - if (flagword & RFLAG) + if (flagword & (RFLAG|CFLAG)) wr_relo(relo, 1); } } @@ -151,7 +151,7 @@ handle_relos(head, sects, names) * Write out the (probably changed) * relocation information. */ - if (flagword & RFLAG) + if (flagword & (RFLAG|CFLAG)) wr_relo(relo, 1); } } diff --git a/util/led/led.6 b/util/led/led.6 index bca1d2fbe..3bfa19e6c 100644 --- a/util/led/led.6 +++ b/util/led/led.6 @@ -97,12 +97,10 @@ run. This flag suppresses the `Undefined:' diagnostic. .TP .B \-c -Only effective in combination with -.BR \-r . -Indicates that relocatable output must be produced, but commons must +Indicates that relocation information must be produced, but commons must be resolved. This may be useful for machines that need a last relocation step -at load time. +at load time. This flag disables the \fB\-r\fP flag. .TP .B \-s `Strip' the output, that is, remove the name table diff --git a/util/led/main.c b/util/led/main.c index bb5d65bfc..85ecd6297 100644 --- a/util/led/main.c +++ b/util/led/main.c @@ -162,9 +162,11 @@ first_pass(argv) break; case 'c': /* - * Might be used in combination with 'r', to produce - * relocatable output, but handle commons now. + * Leave relocation information in the output, so that + * a next pass can see where relocation was done. The + * resulting output however is no longer relocatable. */ + flagword &= ~RFLAG; flagword |= CFLAG; break; #ifndef NDEBUG @@ -188,6 +190,7 @@ first_pass(argv) * given to common symbols, and suppresses the * `Undefined:' diagnostic. */ + if (flagword & CFLAG) break; if (flagword & SFLAG) warning("-r contradicts -s: -s ignored"); flagword |= RFLAG; @@ -360,7 +363,7 @@ evaluate() { norm_commons(); complete_sections(); - if (!(flagword & RFLAG)) + if (!(flagword&RFLAG)) change_names(); } @@ -407,7 +410,7 @@ norm_commons() } name++; } - if ((flagword & RFLAG) && !(flagword & CFLAG)) return; + if (flagword & RFLAG) return; /* * RFLAG is off, so we need not produce relocatable output. @@ -454,18 +457,17 @@ complete_sections() sc->os_foff = foff; foff += sc->os_flen; - if ((flagword & RFLAG) && !(flagword & CFLAG)) + if (flagword & RFLAG) continue; sc->os_size += sect_comm[sectindex]; - if (flagword & RFLAG) continue; sc->os_lign = tstbit(sectindex, lignmap) ? sect_lign[sectindex] : 1; if (tstbit(sectindex, basemap)) { base = sect_base[sectindex]; - if (base % sc->os_lign) + if (sc->os_lign && base % sc->os_lign) fatal("base not aligned"); - } else { + } else if (sc->os_lign) { base += sc->os_lign - 1; base -= base % sc->os_lign; } diff --git a/util/led/memory.c b/util/led/memory.c index abf155548..cef8e5fbd 100644 --- a/util/led/memory.c +++ b/util/led/memory.c @@ -583,7 +583,7 @@ write_bytes() /* * The rest depends on the flags. */ - if (flagword & RFLAG) + if (flagword & (RFLAG|CFLAG)) wr_relo((struct outrelo *) mems[ALLORELO].mem_base, outhead.oh_nrelo); if (!(flagword & SFLAG)) { diff --git a/util/led/output.c b/util/led/output.c index 2b184d539..3a41140b2 100644 --- a/util/led/output.c +++ b/util/led/output.c @@ -30,7 +30,7 @@ beginoutput() if (incore) generate_section_names(); - if (!(flagword & RFLAG)) + if (!(flagword & (CFLAG|RFLAG))) outhead.oh_nrelo = (ushort)0; if (flagword & SFLAG) { outhead.oh_nname = (ushort)0; diff --git a/util/led/relocate.c b/util/led/relocate.c index 9595e7f73..9374d7924 100644 --- a/util/led/relocate.c +++ b/util/led/relocate.c @@ -139,6 +139,7 @@ addrelo(relo, names, valu_out) extern int hash(); extern struct outname *searchname(); extern ushort indexof(); + extern struct outhead outhead; name = searchname(local->on_mptr, hash(local->on_mptr)); if (name == (struct outname *)0) @@ -148,7 +149,11 @@ addrelo(relo, names, valu_out) index += indexof(name); } else { valu += name->on_valu; - index += NGlobals + (name->on_type & S_TYP) - S_MIN; + if ((name->on_type & S_TYP) == S_ABS) { + index += NGlobals + outhead.oh_nsect; + } + else index += NGlobals + + (name->on_type & S_TYP) - S_MIN; } } *valu_out = valu;