aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2006-03-18 14:51:54 +0000
committerEli Zaretskii2006-03-18 14:51:54 +0000
commit8daaf78be89633514b94e661945f0814ea3e1f90 (patch)
treea0b05ee4473d7f60c22bcacd5078f18fbc77e615 /src
parent09b7af0a1c6600f4a2412958ae66b885c79ff5f7 (diff)
downloademacs-8daaf78be89633514b94e661945f0814ea3e1f90.tar.gz
emacs-8daaf78be89633514b94e661945f0814ea3e1f90.zip
[BROKEN_NOCOMBRELOC]: Include assert.h.
(unexec) [BROKEN_NOCOMBRELOC]: Handle platforms whose nocombreloc option is broken (e.g., MIPS/NetBSD).
Diffstat (limited to 'src')
-rw-r--r--src/unexelf.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/unexelf.c b/src/unexelf.c
index 30a35372544..a236b98eab1 100644
--- a/src/unexelf.c
+++ b/src/unexelf.c
@@ -433,6 +433,9 @@ extern void fatal (const char *msgid, ...);
433#if __sgi 433#if __sgi
434#include <syms.h> /* for HDRR declaration */ 434#include <syms.h> /* for HDRR declaration */
435#endif /* __sgi */ 435#endif /* __sgi */
436#ifdef BROKEN_NOCOMBRELOC
437#include <assert.h>
438#endif
436 439
437#ifndef MAP_ANON 440#ifndef MAP_ANON
438#ifdef MAP_ANONYMOUS 441#ifdef MAP_ANONYMOUS
@@ -687,6 +690,9 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
687 int old_mdebug_index; 690 int old_mdebug_index;
688 struct stat stat_buf; 691 struct stat stat_buf;
689 int old_file_size; 692 int old_file_size;
693#ifdef BROKEN_NOCOMBRELOC
694 int unreloc_sections[10], n_unreloc_sections;
695#endif
690 696
691 /* Open the old file, allocate a buffer of the right size, and read 697 /* Open the old file, allocate a buffer of the right size, and read
692 in the file contents. */ 698 in the file contents. */
@@ -1218,6 +1224,7 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
1218 1224
1219 /* This loop seeks out relocation sections for the data section, so 1225 /* This loop seeks out relocation sections for the data section, so
1220 that it can undo relocations performed by the runtime linker. */ 1226 that it can undo relocations performed by the runtime linker. */
1227#ifndef BROKEN_NOCOMBRELOC
1221 for (n = new_file_h->e_shnum - 1; n; n--) 1228 for (n = new_file_h->e_shnum - 1; n; n--)
1222 { 1229 {
1223 ElfW(Shdr) section = NEW_SECTION_H (n); 1230 ElfW(Shdr) section = NEW_SECTION_H (n);
@@ -1272,6 +1279,81 @@ unexec (new_name, old_name, data_start, bss_start, entry_address)
1272 break; 1279 break;
1273 } 1280 }
1274 } 1281 }
1282#else /* BROKEN_NOCOMBRELOC */
1283 for (n = 1, n_unreloc_sections = 0; n < new_file_h->e_shnum; n++)
1284 if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
1285 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata")
1286 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".lit4")
1287 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".lit8")
1288#ifdef IRIX6_5 /* see above */
1289 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".got")
1290#endif
1291 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1")
1292 || !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1"))
1293 {
1294 assert (n_unreloc_sections
1295 < (sizeof (unreloc_sections) / sizeof (unreloc_sections[0])));
1296 unreloc_sections[n_unreloc_sections++] = n;
1297#ifdef DEBUG
1298 fprintf (stderr, "section %d: %s\n", n,
1299 old_section_names + NEW_SECTION_H (n).sh_name);
1300#endif
1301 }
1302
1303 for (n = new_file_h->e_shnum - 1; n; n--)
1304 {
1305 ElfW(Shdr) section = NEW_SECTION_H (n);
1306 caddr_t reloc, end;
1307 ElfW(Addr) addr, offset;
1308 int target;
1309
1310 switch (section.sh_type)
1311 {
1312 default:
1313 break;
1314 case SHT_REL:
1315 case SHT_RELA:
1316 /* This code handles two different size structs, but there should
1317 be no harm in that provided that r_offset is always the first
1318 member. */
1319 for (reloc = old_base + section.sh_offset,
1320 end = reloc + section.sh_size;
1321 reloc < end;
1322 reloc += section.sh_entsize)
1323 {
1324 addr = ((ElfW(Rel) *) reloc)->r_offset;
1325#ifdef __alpha__
1326 /* The Alpha ELF binutils currently have a bug that
1327 sometimes results in relocs that contain all
1328 zeroes. Work around this for now... */
1329 if (addr == 0)
1330 continue;
1331#endif
1332 for (nn = 0; nn < n_unreloc_sections; nn++)
1333 {
1334 target = unreloc_sections[nn];
1335 if (NEW_SECTION_H (target).sh_addr <= addr
1336 && addr < (NEW_SECTION_H (target).sh_addr +
1337 NEW_SECTION_H (target).sh_size))
1338 {
1339 offset = (NEW_SECTION_H (target).sh_addr -
1340 NEW_SECTION_H (target).sh_offset);
1341 memcpy (new_base + addr - offset,
1342 old_base + addr - offset,
1343 sizeof (ElfW(Addr)));
1344#ifdef DEBUG
1345 fprintf (stderr, "unrelocate: [%08lx] <= %08lx\n",
1346 (long) addr,
1347 (long) *((long *) (new_base + addr - offset)));
1348#endif
1349 break;
1350 }
1351 }
1352 }
1353 break;
1354 }
1355 }
1356#endif /* BROKEN_NOCOMBRELOC */
1275 1357
1276 /* Write out new_file, and free the buffers. */ 1358 /* Write out new_file, and free the buffers. */
1277 1359