summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-04-28 11:11:09 +0930
committerAlan Modra <amodra@gmail.com>2023-04-28 15:19:59 +0930
commit143a12bd5a5402231bde748cbbdc22bb3984a522 (patch)
treec01adab6f7c00166fadbcd1f211173715c4ddb0b /bfd
parent4cb2aab8ab9e18d9dfdd8fa362715d70cc2d1109 (diff)
downloadbinutils-gdb-143a12bd5a5402231bde748cbbdc22bb3984a522.tar.gz
Re: Keeping track of rs6000-coff archive element pointers
Commit de7b90610e9e left a hole in the element checking, explained by the comment added to _bfd_xcoff_openr_next_archived_file. While fixing this, tidy some types used to hold unsigned values so that casts are not needed to avoid signed/unsigned comparison warnings. Also tidy a few things in xcoff.h. bfd/ * coff-rs6000.c (_bfd_xcoff_openr_next_archived_file): Check that we aren't pointing back at the last element. Make filestart a ufile_ptr. Update for xcoff_artdata change. (_bfd_strntol, _bfd_strntoll): Return unsigned values. (_bfd_xcoff_slurp_armap): Make off a ufile_ptr. (add_ranges): Update for xcoff_artdata change. * libbfd-in.h (struct artdata): Make first_file_filepos a ufile_ptr. * libbfd.h: Regenerate. include/ * coff/xcoff.h (struct xcoff_artdata): Replace min_elt with ar_hdr_size. (xcoff_big_format_p): In the !SMALL_ARCHIVE case return true for anything but a small archive.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/coff-rs6000.c35
-rw-r--r--bfd/libbfd-in.h2
-rw-r--r--bfd/libbfd.h2
3 files changed, 28 insertions, 11 deletions
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 3b451912df7..421dc8f7ee5 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1294,7 +1294,7 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
take a maximum length as an additional parameter. Also - just to save space,
we omit the endptr return parameter, since we know that it is never used. */
-static long
+static unsigned long
_bfd_strntol (const char * nptr, int base, unsigned int maxlen)
{
char buf[24]; /* Should be enough. */
@@ -1306,7 +1306,7 @@ _bfd_strntol (const char * nptr, int base, unsigned int maxlen)
return strtol (buf, NULL, base);
}
-static long long
+static unsigned long long
_bfd_strntoll (const char * nptr, int base, unsigned int maxlen)
{
char buf[32]; /* Should be enough. */
@@ -1338,7 +1338,7 @@ _bfd_strntoll (const char * nptr, int base, unsigned int maxlen)
bool
_bfd_xcoff_slurp_armap (bfd *abfd)
{
- file_ptr off;
+ ufile_ptr off;
size_t namlen;
bfd_size_type sz;
bfd_byte *contents, *cend;
@@ -1636,7 +1636,8 @@ add_range (bfd *abfd, ufile_ptr start, ufile_ptr end)
/* Overlap with another element. */
goto err;
- unsigned min_elt = x_artdata (abfd)->min_elt;
+ /* A zero size element with a one char name is this big. */
+ unsigned min_elt = x_artdata (abfd)->ar_hdr_size + 2 + SXCOFFARFMAG;
if (start - lo->end < min_elt)
{
/* Merge into an existing range. */
@@ -1757,7 +1758,7 @@ _bfd_xcoff_read_ar_hdr (bfd *abfd)
bfd *
_bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
{
- file_ptr filestart;
+ ufile_ptr filestart;
if (x_artdata (archive) == NULL)
{
@@ -1770,10 +1771,10 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
if (last_file == NULL)
{
filestart = bfd_ardata (archive)->first_file_filepos;
- if (x_artdata (archive)->min_elt == 0)
+ if (x_artdata (archive)->ar_hdr_size == 0)
{
x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR;
- x_artdata (archive)->min_elt = SIZEOF_AR_HDR + SXCOFFARFMAG + 2;
+ x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR;
}
}
else
@@ -1794,10 +1795,10 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
if (last_file == NULL)
{
filestart = bfd_ardata (archive)->first_file_filepos;
- if (x_artdata (archive)->min_elt == 0)
+ if (x_artdata (archive)->ar_hdr_size == 0)
{
x_artdata (archive)->ranges.end = SIZEOF_AR_FILE_HDR_BIG;
- x_artdata (archive)->min_elt = SIZEOF_AR_HDR_BIG + SXCOFFARFMAG + 2;
+ x_artdata (archive)->ar_hdr_size = SIZEOF_AR_HDR_BIG;
}
}
else
@@ -1814,6 +1815,22 @@ _bfd_xcoff_openr_next_archived_file (bfd *archive, bfd *last_file)
}
}
+ /* Check that we aren't pointing back at the last element. This is
+ necessary depite the add_range checking in _bfd_xcoff_read_ar_hdr
+ because archive.c leaves the last element open and thus in the
+ archive element cache until the next element is opened. */
+ if (last_file != NULL)
+ {
+ ufile_ptr laststart = last_file->proxy_origin;
+ laststart -= x_artdata (archive)->ar_hdr_size;
+ laststart -= arch_eltdata (last_file)->extra_size;
+ if (filestart == laststart)
+ {
+ bfd_set_error (bfd_error_malformed_archive);
+ return NULL;
+ }
+ }
+
return _bfd_get_elt_at_filepos (archive, filestart, NULL);
}
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 68b5343fd2e..4305b8416ea 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -72,7 +72,7 @@ extern unsigned int _bfd_section_id ATTRIBUTE_HIDDEN;
struct artdata
{
- file_ptr first_file_filepos;
+ ufile_ptr first_file_filepos;
/* Speed up searching the armap */
htab_t cache;
carsym *symdefs; /* The symdef entries. */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index bb7f2f1efcf..aceec4ab9c0 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -78,7 +78,7 @@ extern unsigned int _bfd_section_id ATTRIBUTE_HIDDEN;
struct artdata
{
- file_ptr first_file_filepos;
+ ufile_ptr first_file_filepos;
/* Speed up searching the armap */
htab_t cache;
carsym *symdefs; /* The symdef entries. */