summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/ld/rrs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/ld/rrs.c')
-rw-r--r--gnu/usr.bin/ld/rrs.c395
1 files changed, 213 insertions, 182 deletions
diff --git a/gnu/usr.bin/ld/rrs.c b/gnu/usr.bin/ld/rrs.c
index 93ad89b..2d1b3bc 100644
--- a/gnu/usr.bin/ld/rrs.c
+++ b/gnu/usr.bin/ld/rrs.c
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: rrs.c,v 1.12 1994/06/15 22:39:52 rich Exp $
+ * $Id: rrs.c,v 1.13 1994/12/23 22:30:48 nate Exp $
*/
#include <sys/param.h>
@@ -64,8 +64,8 @@ static int reserved_rrs_relocs;
static int claimed_rrs_relocs;
static int discarded_rrs_relocs;
-static int number_of_gotslots;
-static int number_of_jmpslots;
+static int number_of_gotslots = 1;
+static int number_of_jmpslots = 1;
static int number_of_rrs_hash_entries;
static int number_of_rrs_symbols;
static int rrs_strtab_size;
@@ -73,10 +73,14 @@ static int rrs_symbol_size;
static int current_jmpslot_offset;
static int current_got_offset;
+static int got_origin;
static int current_reloc_offset;
static int current_hash_index;
int number_of_shobjs;
+/* Convert a GOT offset into a table entry */
+#define GOTP(off) ((got_t *)((long)rrs_got + got_origin + (off)))
+
struct shobj {
struct shobj *next;
struct file_entry *entry;
@@ -125,9 +129,10 @@ RRS data segment:
| |
| sdt |
| |
- +-------------------+ <-- _GLOBAL_OFFSET_TABLE_ (sdt_got)
+ +-------------------+ <-- sdt_got
| |
- | _GOT_ |
+ | _GOT_ | <-- _GLOBAL_OFFSET_TABLE_
+ | | ( == sdt_got + got_origin)
| |
+-------------------+ <-- sdt_plt
| |
@@ -137,37 +142,12 @@ RRS data segment:
*/
/*
- * Initialize RRS
- */
-
-void
-init_rrs()
-{
- reserved_rrs_relocs = 0;
- claimed_rrs_relocs = 0;
- discarded_rrs_relocs = 0;
-
- number_of_rrs_symbols = 0;
- rrs_strtab_size = 0;
-
- /* First jmpslot reserved for run-time binder */
- current_jmpslot_offset = sizeof(jmpslot_t);
- number_of_jmpslots = 1;
-
- /* First gotslot reserved for __DYNAMIC */
- current_got_offset = sizeof(got_t);
- number_of_gotslots = 1;
-
- current_reloc_offset = 0;
-}
-
-/*
* Add NAME to the list of needed run-time objects.
* Return 1 if ENTRY was added to the list.
*/
int
rrs_add_shobj(entry)
-struct file_entry *entry;
+ struct file_entry *entry;
{
struct shobj **p;
@@ -184,8 +164,8 @@ struct file_entry *entry;
void
alloc_rrs_reloc(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
#ifdef DEBUG
printf("alloc_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
@@ -195,8 +175,8 @@ printf("alloc_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
void
alloc_rrs_segment_reloc(entry, r)
-struct file_entry *entry;
-struct relocation_info *r;
+ struct file_entry *entry;
+ struct relocation_info *r;
{
#ifdef DEBUG
printf("alloc_rrs_segment_reloc at %#x in %s\n",
@@ -207,30 +187,31 @@ printf("alloc_rrs_segment_reloc at %#x in %s\n",
void
alloc_rrs_jmpslot(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
- if (sp->jmpslot_offset == -1) {
- sp->jmpslot_offset = current_jmpslot_offset;
- current_jmpslot_offset += sizeof(jmpslot_t);
- number_of_jmpslots++;
- reserved_rrs_relocs++;
- }
+ if (sp->flags & GS_HASJMPSLOT)
+ return;
+
+ sp->flags |= GS_HASJMPSLOT;
+ number_of_jmpslots++;
+ reserved_rrs_relocs++;
}
void
alloc_rrs_gotslot(entry, r, lsp)
-struct file_entry *entry;
-struct relocation_info *r;
-struct localsymbol *lsp;
+ struct file_entry *entry;
+ struct relocation_info *r;
+ struct localsymbol *lsp;
{
symbol *sp = lsp->symbol;
if (!RELOC_EXTERN_P(r)) {
if (sp != NULL) {
- warnx("%s: relocation for internal symbol expected at %#x",
- get_file_name(entry), RELOC_ADDRESS(r));
+ warnx("%s: relocation for internal symbol "
+ "expected at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
return;
}
@@ -238,38 +219,37 @@ struct localsymbol *lsp;
/* No need for a GOT slot */
return;
- if (lsp->gotslot_offset == -1) {
- lsp->gotslot_offset = current_got_offset;
- current_got_offset += sizeof(got_t);
- number_of_gotslots++;
- reserved_rrs_relocs++;
- }
+ if (lsp->flags & LS_HASGOTSLOT)
+ return;
+
+ lsp->flags |= LS_HASGOTSLOT;
} else {
if (sp == NULL) {
- warnx("%s: relocation must refer to global symbol at %#x",
- get_file_name(entry), RELOC_ADDRESS(r));
+ warnx("%s: relocation must refer "
+ "to global symbol at %#x",
+ get_file_name(entry), RELOC_ADDRESS(r));
return;
}
if (sp->alias)
sp = sp->alias;
- if (sp->gotslot_offset == -1) {
- sp->gotslot_offset = current_got_offset;
- current_got_offset += sizeof(got_t);
- number_of_gotslots++;
- reserved_rrs_relocs++;
- }
+ if (sp->flags & GS_HASGOTSLOT)
+ return;
+
+ sp->flags |= GS_HASGOTSLOT;
}
+ number_of_gotslots++;
+ reserved_rrs_relocs++;
}
void
alloc_rrs_cpy_reloc(entry, sp)
-struct file_entry *entry;
-symbol *sp;
+ struct file_entry *entry;
+ symbol *sp;
{
if (sp->flags & GS_CPYRELOCRESERVED)
return;
@@ -302,10 +282,10 @@ rrs_next_reloc()
*/
int
claim_rrs_reloc(entry, rp, sp, relocation)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
-long *relocation;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
+ long *relocation;
{
struct relocation_info *r = rrs_next_reloc();
@@ -322,7 +302,7 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
if (link_mode & SYMBOLIC) {
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
RELOC_EXTERN_P(r) = 0;
*relocation += sp->value;
(void) md_make_reloc(rp, r, RELTYPE_RELATIVE);
@@ -338,28 +318,31 @@ printf("claim_rrs_reloc: %s in %s\n", sp->name, get_file_name(entry));
*/
long
claim_rrs_jmpslot(entry, rp, sp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
+ long addend;
{
struct relocation_info *r;
- if (sp->flags & GS_JMPSLOTCLAIMED)
+ if (!(sp->flags & GS_HASJMPSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_jmpslot: %s: no reservation",
+ get_file_name(entry),
+ sp->name);
+
+ if (sp->jmpslot_offset != -1)
return rrs_sdt.sdt_plt + sp->jmpslot_offset;
+ sp->jmpslot_offset = current_jmpslot_offset;
+ current_jmpslot_offset += sizeof(jmpslot_t);
+
#ifdef DEBUG
printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
get_file_name(entry),
sp->name, sp->rrs_symbolnum, sp->jmpslot_offset);
#endif
- if (sp->jmpslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_jmpslot: %s: jmpslot_offset == -1\n",
- get_file_name(entry),
- sp->name);
-
if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
@@ -370,7 +353,6 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
sp->value);
if (rrs_section_type == RRS_PARTIAL || !JMPSLOT_NEEDS_RELOC) {
/* PLT is self-contained */
- sp->flags |= GS_JMPSLOTCLAIMED;
discarded_rrs_relocs++;
return rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
@@ -384,7 +366,6 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
* Install a run-time relocation for this PLT entry.
*/
r = rrs_next_reloc();
- sp->flags |= GS_JMPSLOTCLAIMED;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
@@ -408,10 +389,10 @@ printf("claim_rrs_jmpslot: %s: %s(%d) -> offset %x\n",
*/
long
claim_rrs_gotslot(entry, rp, lsp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-struct localsymbol *lsp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ struct localsymbol *lsp;
+ long addend;
{
struct relocation_info *r;
symbol *sp = lsp->symbol;
@@ -424,28 +405,42 @@ long addend;
if (sp->alias)
sp = sp->alias;
-#ifdef DEBUG
-printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
- sp->name, sp->rrs_symbolnum, sp->value, sp->gotslot_offset, addend);
-#endif
- if (sp->gotslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_gotslot: %s: gotslot_offset == -1\n",
+ if (!(sp->flags & GS_HASGOTSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_gotslot: %s: no reservation",
get_file_name(entry), sp->name);
- if (sp->flags & GS_GOTSLOTCLAIMED) {
-#ifdef DEBUG
- if (*(long *)((long)rrs_got + sp->gotslot_offset) != addend +
- (!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))
- ?sp->value:0)
- errx(1, "%s: %s: gotslot at %#x is multiple valued\n",
+ if (sp->gotslot_offset != -1) {
+#ifdef DIAGNOSTIC
+ if (*GOTP(sp->gotslot_offset) != addend +
+ ((!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))
+ ? sp->value : 0))
+ errx(1, "%s: %s: gotslot at %#x is multiple valued, "
+ "*got = %#x, addend = %#x, sp->value = %#x",
get_file_name(entry), sp->name,
- sp->gotslot_offset);
+ sp->gotslot_offset,
+ *GOTP(sp->gotslot_offset), addend, sp->value);
#endif
/* This symbol already passed here before. */
return sp->gotslot_offset;
}
+ if (current_got_offset == 0)
+ /* GOT offset 0 is reserved */
+ current_got_offset += sizeof(got_t);
+
+ if (current_got_offset > MAX_GOTOFF)
+ errx(1, "%s: GOT overflow on symbol `%s' at %#x",
+ get_file_name(entry), sp->name, RELOC_ADDRESS(rp));
+
+ sp->gotslot_offset = current_got_offset;
+ current_got_offset += sizeof(got_t);
+
+#ifdef DEBUG
+printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
+ sp->name, sp->rrs_symbolnum, sp->value, sp->gotslot_offset, addend);
+#endif
+
if (sp->defined &&
(!(link_mode & SHAREABLE) || (link_mode & SYMBOLIC))) {
@@ -453,8 +448,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* Reduce to just a base-relative translation.
*/
- *(got_t *)((long)rrs_got + sp->gotslot_offset) =
- sp->value + addend;
+ *GOTP(sp->gotslot_offset) = sp->value + addend;
reloc_type = RELTYPE_RELATIVE;
} else if ((link_mode & SYMBOLIC) || rrs_section_type == RRS_PARTIAL) {
@@ -464,7 +458,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* so again all symbols must be known.
*/
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
} else {
@@ -472,7 +466,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* This gotslot will be updated with symbol value at run-time.
*/
- *(got_t *)((long)rrs_got + sp->gotslot_offset) = addend;
+ *GOTP(sp->gotslot_offset) = addend;
}
if (rrs_section_type == RRS_PARTIAL) {
@@ -483,9 +477,8 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
*/
if (!sp->defined)
warnx("Cannot reduce symbol \"%s\" in %s",
- sp->name, get_file_name(entry));
+ sp->name, get_file_name(entry));
discarded_rrs_relocs++;
- sp->flags |= GS_GOTSLOTCLAIMED;
return sp->gotslot_offset;
}
@@ -498,8 +491,7 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
* as no symbol need be looked up at run-time.
*/
r = rrs_next_reloc();
- sp->flags |= GS_GOTSLOTCLAIMED;
- r->r_address = rrs_sdt.sdt_got + sp->gotslot_offset;
+ r->r_address = got_symbol->value + sp->gotslot_offset;
RELOC_SYMBOL(r) = sp->rrs_symbolnum;
RELOC_EXTERN_P(r) = !(reloc_type == RELTYPE_RELATIVE);
md_make_gotreloc(rp, r, reloc_type);
@@ -515,40 +507,50 @@ printf("claim_rrs_gotslot: %s(%d,%#x) slot offset %#x, addend %#x\n",
*/
long
claim_rrs_internal_gotslot(entry, rp, lsp, addend)
-struct file_entry *entry;
-struct relocation_info *rp;
-struct localsymbol *lsp;
-long addend;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ struct localsymbol *lsp;
+ long addend;
{
struct relocation_info *r;
addend += lsp->nzlist.nz_value;
if (!RELOC_STATICS_THROUGH_GOT_P(r))
- return addend - rrs_sdt.sdt_got;
-
-#ifdef DEBUG
-printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
- get_file_name(entry), lsp->gotslot_offset, addend);
-#endif
+ return addend - got_symbol->value;
- if (lsp->gotslot_offset == -1)
- errx(1,
- "internal error: %s: claim_rrs_internal_gotslot at %#x: slot_offset == -1\n",
+ if (!(lsp->flags & LS_HASGOTSLOT))
+ errx(1, "internal error: "
+ "%s: claim_rrs_internal_gotslot at %#x: no reservation",
get_file_name(entry), RELOC_ADDRESS(rp));
- if (lsp->flags & LS_GOTSLOTCLAIMED) {
- /* Already done */
- if (addend != *(long *)((long)rrs_got + lsp->gotslot_offset))
- errx(1, "%s: gotslot at %#x is multiple valued\n",
+ if (lsp->gotslot_offset != -1) {
+ /* Already claimed */
+ if (*GOTP(lsp->gotslot_offset) != addend)
+ errx(1, "%s: gotslot at %#x is multiple valued",
get_file_name(entry), lsp->gotslot_offset);
return lsp->gotslot_offset;
}
- *(long *)((long)rrs_got + lsp->gotslot_offset) = addend;
+ if (current_got_offset == 0)
+ /* GOT offset 0 is reserved */
+ current_got_offset += sizeof(got_t);
+
+ if (current_got_offset > MAX_GOTOFF)
+ errx(1, "%s: GOT overflow for relocation at %#x",
+ get_file_name(entry), RELOC_ADDRESS(rp));
+
+ lsp->gotslot_offset = current_got_offset;
+ current_got_offset += sizeof(got_t);
+
+ *GOTP(lsp->gotslot_offset) = addend;
+
+#ifdef DEBUG
+printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
+ get_file_name(entry), lsp->gotslot_offset, addend);
+#endif
if (rrs_section_type == RRS_PARTIAL) {
- lsp->flags |= LS_GOTSLOTCLAIMED;
discarded_rrs_relocs++;
return lsp->gotslot_offset;
}
@@ -557,8 +559,7 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
* Relocation entry needed for this static GOT entry.
*/
r = rrs_next_reloc();
- lsp->flags |= LS_GOTSLOTCLAIMED;
- r->r_address = rrs_sdt.sdt_got + lsp->gotslot_offset;
+ r->r_address = got_symbol->value + lsp->gotslot_offset;
RELOC_EXTERN_P(r) = 0;
md_make_gotreloc(rp, r, RELTYPE_RELATIVE);
return lsp->gotslot_offset;
@@ -566,9 +567,9 @@ printf("claim_rrs_internal_gotslot: %s: slot offset %#x, addend = %#x\n",
void
claim_rrs_cpy_reloc(entry, rp, sp)
-struct file_entry *entry;
-struct relocation_info *rp;
-symbol *sp;
+ struct file_entry *entry;
+ struct relocation_info *rp;
+ symbol *sp;
{
struct relocation_info *r;
@@ -576,8 +577,8 @@ symbol *sp;
return;
if (!(sp->flags & GS_CPYRELOCRESERVED))
- errx(1,
- "internal error: %s: claim_cpy_reloc: %s: no reservation\n",
+ errx(1, "internal error: "
+ "%s: claim_cpy_reloc: %s: no reservation",
get_file_name(entry), sp->name);
#ifdef DEBUG
@@ -595,8 +596,8 @@ printf("claim_rrs_copy: %s: %s -> %x\n",
void
claim_rrs_segment_reloc(entry, rp)
-struct file_entry *entry;
-struct relocation_info *rp;
+ struct file_entry *entry;
+ struct relocation_info *rp;
{
struct relocation_info *r = rrs_next_reloc();
@@ -618,8 +619,8 @@ printf("claim_rrs_segment_reloc: %s at %#x\n",
*/
void
rrs_insert_hash(cp, index)
-char *cp;
-int index;
+ char *cp;
+ int index;
{
int hashval = 0;
struct rrs_hash *hp;
@@ -699,6 +700,8 @@ consider_rrs_section_lengths()
if (rrs_section_type == RRS_NONE) {
got_symbol->defined = 0;
+ if (reserved_rrs_relocs > 0)
+ errx(1, "internal error: empty RRS has reservations");
return;
}
@@ -781,7 +784,8 @@ consider_rrs_section_lengths()
if (rrs_sdt.sdt_buckets < 4)
rrs_sdt.sdt_buckets = 4;
- number_of_rrs_hash_entries = rrs_sdt.sdt_buckets + number_of_rrs_symbols;
+ number_of_rrs_hash_entries = rrs_sdt.sdt_buckets +
+ number_of_rrs_symbols;
rrs_hashtab = (struct rrs_hash *)xmalloc(
number_of_rrs_hash_entries * sizeof(struct rrs_hash));
for (n = 0; n < rrs_sdt.sdt_buckets; n++)
@@ -838,11 +842,32 @@ relocate_rrs_addresses()
dynamic_symbol->value = 0;
+ /*
+ * Get ready to allocate linkage table offsets.
+ * First jmpslot is reserved for the run-time binder
+ * GOT entry at offset 0 is reserved for `__DYNAMIC'.
+ */
+ current_jmpslot_offset = sizeof(jmpslot_t);
+ current_got_offset = 0;
+
+ if (1 /* Not "-fPIC" seen */) {
+ int gotsize = number_of_gotslots * sizeof(got_t);
+
+ if (gotsize + MIN_GOTOFF - (int)sizeof(got_t) > MAX_GOTOFF)
+ warnx("Global Offset Table overflow");
+ if (gotsize > MAX_GOTOFF)
+ /* Position at "two-complements" origin */
+ current_got_offset += MIN_GOTOFF;
+ }
+
+ got_origin = -current_got_offset;
+
if (rrs_section_type == RRS_NONE)
return;
if (rrs_section_type == RRS_PARTIAL) {
- got_symbol->value = rrs_sdt.sdt_got = rrs_data_start;
+ rrs_sdt.sdt_got = rrs_data_start;
+ got_symbol->value = rrs_sdt.sdt_got + got_origin;
rrs_sdt.sdt_plt = rrs_sdt.sdt_got +
number_of_gotslots * sizeof(got_t);
return;
@@ -889,12 +914,11 @@ relocate_rrs_addresses()
rrs_sdt.sdt_filler2 = 0;
/*
- * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC
- * &__DYNAMIC is also in the first GOT entry.
+ * Assign addresses to _GLOBAL_OFFSET_TABLE_ and __DYNAMIC.
+ * The value `&__DYNAMIC' is in the GOT table at offset 0.
*/
- got_symbol->value = rrs_sdt.sdt_got;
-
- *rrs_got = dynamic_symbol->value = rrs_data_start;
+ got_symbol->value = rrs_sdt.sdt_got + got_origin;
+ *GOTP(0) = dynamic_symbol->value = rrs_data_start;
}
@@ -907,36 +931,37 @@ write_rrs_data()
return;
pos = rrs_data_start + (N_DATOFF(outheader) - DATA_START(outheader));
- if (lseek(outdesc, pos, L_SET) != pos)
- err(1, "write_rrs_data: lseek");
+ if (fseek(outstream, pos, SEEK_SET) != 0)
+ err(1, "write_rrs_data: fseek");
if (rrs_section_type == RRS_PARTIAL) {
/*
* Only a GOT and PLT are needed.
*/
md_swapout_got(rrs_got, number_of_gotslots);
- mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
+ mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
- mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
+ mywrite(rrs_plt, number_of_jmpslots,
+ sizeof(jmpslot_t), outstream);
return;
}
md_swapout__dynamic(&rrs_dyn);
- mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outdesc);
+ mywrite(&rrs_dyn, 1, sizeof(struct _dynamic), outstream);
md_swapout_so_debug(&rrs_so_debug);
- mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outdesc);
+ mywrite(&rrs_so_debug, 1, sizeof(struct so_debug), outstream);
md_swapout_section_dispatch_table(&rrs_sdt);
- mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outdesc);
+ mywrite(&rrs_sdt, 1, sizeof(struct section_dispatch_table), outstream);
md_swapout_got(rrs_got, number_of_gotslots);
- mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outdesc);
+ mywrite(rrs_got, number_of_gotslots, sizeof(got_t), outstream);
md_swapout_jmpslot(rrs_plt, number_of_jmpslots);
- mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outdesc);
+ mywrite(rrs_plt, number_of_jmpslots, sizeof(jmpslot_t), outstream);
}
void
@@ -949,23 +974,24 @@ write_rrs_text()
int offset = 0;
struct shobj *shp;
struct sod *sodp;
+ int bind;
if (rrs_section_type == RRS_PARTIAL)
return;
pos = rrs_text_start + (N_TXTOFF(outheader) - TEXT_START(outheader));
- if (lseek(outdesc, pos, L_SET) != pos)
- err(1, "write_rrs_text: lseek");
+ if (fseek(outstream, pos, SEEK_SET) != 0)
+ err(1, "write_rrs_text: fseek");
/* Write relocation records */
md_swapout_reloc(rrs_reloc, reserved_rrs_relocs);
mywrite(rrs_reloc, reserved_rrs_relocs,
- sizeof(struct relocation_info), outdesc);
+ sizeof(struct relocation_info), outstream);
/* Write the RRS symbol hash tables */
md_swapout_rrs_hash(rrs_hashtab, number_of_rrs_hash_entries);
mywrite(rrs_hashtab, number_of_rrs_hash_entries,
- sizeof(struct rrs_hash), outdesc);
+ sizeof(struct rrs_hash), outstream);
/*
* Determine size of an RRS symbol entry, allocate space
@@ -1028,8 +1054,8 @@ write_rrs_text()
if ((long)nlp - (long)rrs_symbols >=
number_of_rrs_symbols * rrs_symbol_size)
- errx(1,
- "internal error: rrs symbols exceed allocation %d ",
+ errx(1, "internal error: "
+ "rrs symbols exceed allocation %d",
number_of_rrs_symbols);
nlp->nz_desc = 0;
@@ -1037,6 +1063,8 @@ write_rrs_text()
if (LD_VERSION_NZLIST_P(soversion))
nlp->nz_size = 0;
+ bind = (sp->flags & GS_WEAK) ? BIND_WEAK : 0;
+
if (sp->defined > 1) {
/* defined with known type */
if (!(link_mode & SHAREABLE) &&
@@ -1049,7 +1077,7 @@ write_rrs_text()
*/
nlp->nz_type = sp->alias->defined;
nlp->nz_value = sp->alias->value;
- nlp->nz_other = N_OTHER(0, sp->alias->aux);
+ nlp->nz_other = N_OTHER(bind, sp->alias->aux);
} else if (sp->defined == N_SIZE) {
/*
* Make sure this symbol isn't going
@@ -1060,35 +1088,38 @@ write_rrs_text()
} else {
nlp->nz_type = sp->defined;
nlp->nz_value = sp->value;
- nlp->nz_other = N_OTHER(0, sp->aux);
+ nlp->nz_other = N_OTHER(bind, sp->aux);
}
if (LD_VERSION_NZLIST_P(soversion))
nlp->nz_size = sp->size;
} else if (sp->common_size) {
/*
- * a common definition
+ * A common definition.
*/
nlp->nz_type = N_UNDF | N_EXT;
nlp->nz_value = sp->common_size;
+ nlp->nz_other = N_OTHER(bind, 0);
} else if (!sp->defined) {
/* undefined */
nlp->nz_type = N_UNDF | N_EXT;
nlp->nz_value = 0;
if (sp->so_defined && sp->jmpslot_offset != -1) {
/*
- * Define a "weak" function symbol.
+ * A PLT entry. The auxiliary type -- which
+ * must be AUX_FUNC -- is used by the run-time
+ * linker to unambiguously resolve function
+ * address references.
*/
if (sp->aux != AUX_FUNC)
errx(1, "%s: non-function jmpslot",
- sp->name);
- nlp->nz_other = N_OTHER(0, sp->aux);
+ sp->name);
+ nlp->nz_other = N_OTHER(bind, sp->aux);
nlp->nz_value =
rrs_sdt.sdt_plt + sp->jmpslot_offset;
}
} else
- errx(1,
- "internal error: %s defined in mysterious way",
- sp->name);
+ errx(1, "internal error: %s defined in mysterious way",
+ sp->name);
/* Set symbol's name */
nlp->nz_strx = offset;
@@ -1103,7 +1134,7 @@ write_rrs_text()
int t = (nlp->nz_type == N_INDR + N_EXT);
INCR_NLP(nlp);
- nlp->nz_type = N_UNDF + t?N_EXT:0;
+ nlp->nz_type = N_UNDF + (t ? N_EXT : 0);
nlp->nz_un.n_strx = offset;
nlp->nz_value = 0;
nlp->nz_other = 0;
@@ -1118,8 +1149,8 @@ write_rrs_text()
} END_EACH_SYMBOL;
if (MALIGN(offset) != rrs_strtab_size)
- errx(1,
- "internal error: inconsistent RRS string table length: %d, expected %d",
+ errx(1, "internal error: "
+ "inconsistent RRS string table length: %d, expected %d",
offset, rrs_strtab_size);
/* Write the symbol table */
@@ -1127,10 +1158,10 @@ write_rrs_text()
md_swapout_symbols(rrs_symbols, number_of_rrs_symbols);
else
md_swapout_zsymbols(rrs_symbols, number_of_rrs_symbols);
- mywrite(rrs_symbols, symsize, 1, outdesc);
+ mywrite(rrs_symbols, symsize, 1, outstream);
/* Write the strings */
- mywrite(rrs_strtab, rrs_strtab_size, 1, outdesc);
+ mywrite(rrs_strtab, rrs_strtab_size, 1, outstream);
/*
* Write the names of the shared objects needed at run-time
@@ -1161,12 +1192,12 @@ write_rrs_text()
}
if (i < number_of_shobjs)
- errx(1,
- "internal error: # of link objects less then expected %d",
+ errx(1, "internal error: "
+ "# of link objects less then expected %d",
number_of_shobjs);
md_swapout_sod(sodp, number_of_shobjs);
- mywrite(sodp, number_of_shobjs, sizeof(struct sod), outdesc);
+ mywrite(sodp, number_of_shobjs, sizeof(struct sod), outstream);
for (i = 0, shp = rrs_shobjs; shp; i++, shp = shp->next) {
char *name = shp->entry->local_sym_name;
@@ -1175,7 +1206,7 @@ write_rrs_text()
name += 2;
}
- mywrite(name, strlen(name) + 1, 1, outdesc);
+ mywrite(name, strlen(name) + 1, 1, outstream);
}
}
@@ -1188,8 +1219,8 @@ write_rrs()
*/
if (rrs_section_type == RRS_NONE) {
if (reserved_rrs_relocs > 1)
- errx(1,
- "internal error: RRS relocs in static program: %d",
+ errx(1, "internal error: "
+ "RRS relocs in static program: %d",
reserved_rrs_relocs-1);
return;
}
@@ -1202,8 +1233,8 @@ printf("rrs_relocs: reserved %d claimed %d discarded %d, gotslots %d jmpslots %d
/* Final consistency check */
if (claimed_rrs_relocs + discarded_rrs_relocs != reserved_rrs_relocs) {
- errx(1,
- "internal error: reserved relocs(%d) != claimed(%d) + discarded(%d)",
+ errx(1, "internal error: "
+ "reserved relocs(%d) != claimed(%d) + discarded(%d)",
reserved_rrs_relocs,
claimed_rrs_relocs,
discarded_rrs_relocs);
OpenPOWER on IntegriCloud