[PATCH v2 11/15] MIPS: Fix line info in compressed MIPS function
Jovan Dmitrovic
jovan.dmitrovic@htecgroup.com
Wed Oct 29 14:09:41 GMT 2025
From: Matthew Fortune <matthew.fortune@mips.com>
This fix allows the first address of a MIPS16/microMIPS function to
be used to get the filename/line and function that it belongs to
whereas it has previously needed the ISA bit to be set in the address
for the first instruction to match up correctly.
Note: we should really be checking the output of addr2line, but the
binutils test-framework doesn't have that capability yet.
Expected addr2line output for both new tests is:
$ addr2line -a 0x400000 0x400004 0x40000c -p -e <elf>
0x00400000: .*-lineno.c:1
0x00400004: .*-lineno.c:2
0x0040000c: .*-lineno.c:3
Signed-off-by: Faraz Shahbazker <fshahbazker@wavecomp.com>
Signed-off-by: Milica Matic <milica.matic@htecgroup.com>
Signed-off-by: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
bfd/ChangeLog:
* elfxx-mips.c (_bfd_mips_elf_find_nearest_line): If no matching
line is found for an address, retry with the ISA bit set in case
searching at the beginning of a MIPS16/microMIPS section.
ld/testsuite/ChangeLog:
* ld-mips-elf/mips16-lineno.s: New test source.
* ld-mips-elf/micromips-lineno.s: New test source.
* ld-mips-elf/mips16-lineno.d: New test.
* ld-mips-elf/micromips-lineno.d: New test.
* ld-mips-elf/mips-elf.exp: Run the new tests
---
bfd/elfxx-mips.c | 19 +++++++--
ld/testsuite/ld-mips-elf/micromips-lineno.d | 33 +++++++++++++++
ld/testsuite/ld-mips-elf/micromips-lineno.s | 44 ++++++++++++++++++++
ld/testsuite/ld-mips-elf/mips-elf.exp | 4 ++
ld/testsuite/ld-mips-elf/mips16-lineno.d | 31 ++++++++++++++
ld/testsuite/ld-mips-elf/mips16-lineno.s | 46 +++++++++++++++++++++
6 files changed, 174 insertions(+), 3 deletions(-)
create mode 100644 ld/testsuite/ld-mips-elf/micromips-lineno.d
create mode 100644 ld/testsuite/ld-mips-elf/micromips-lineno.s
create mode 100644 ld/testsuite/ld-mips-elf/mips16-lineno.d
create mode 100644 ld/testsuite/ld-mips-elf/mips16-lineno.s
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index ba2c8202d28..1121473f146 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -13495,6 +13495,7 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
unsigned int *discriminator_ptr)
{
asection *msec;
+ bool found = false;
if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
filename_ptr, functionname_ptr,
@@ -13585,9 +13586,21 @@ _bfd_mips_elf_find_nearest_line (bfd *abfd, asymbol **symbols,
/* Fall back on the generic ELF find_nearest_line routine. */
- return _bfd_elf_find_nearest_line (abfd, symbols, section, offset,
- filename_ptr, functionname_ptr,
- line_ptr, discriminator_ptr);
+ found = _bfd_elf_find_nearest_line (abfd, symbols, section, offset,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr);
+
+ /* The bfd_find_nearest_line_discriminator may not be able to find filename
+ and line if pc points to start of a MIPS compressed function. This is
+ because ISA bit is set in the line number entries. For example, if start
+ of a function is 0x80200750 then line number entries start from 0x80200751
+ (31st bit is set). Set ISA bit of the pc and search again.
+ if (found && *filename_ptr == NULL && *line_ptr == 0 && (offset & 1) == 0)
+ found = _bfd_elf_find_nearest_line (abfd, symbols, section,
+ offset | 1,
+ filename_ptr, functionname_ptr,
+ line_ptr, discriminator_ptr); */
+ return found;
}
bool
diff --git a/ld/testsuite/ld-mips-elf/micromips-lineno.d b/ld/testsuite/ld-mips-elf/micromips-lineno.d
new file mode 100644
index 00000000000..8a927246365
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/micromips-lineno.d
@@ -0,0 +1,33 @@
+#name: MICROMIPS address mapping to debug line information
+#as: -march=mips64r6
+#ld: -Ttext 0x400020
+#objdump: -dlr
+#source: micromips-lineno.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+
+00400020 <__start>:
+ \.\.\.
+
+00400030 <foo>:
+foo\(\):
+ 400030: 0c00 nop
+.*micromips-lineno.c:1
+ 400032: 47e3 jrc ra
+
+00400034 <bar>:
+.*micromips-lineno.c:2
+ 400034: 03e00009 jr ra
+bar\(\):
+.*micromips-lineno.c:2
+ 400038: 00000000 nop
+
+0040003c <baz>:
+baz\(\):
+ 40003c: 0c00 nop
+.*micromips-lineno.c:3
+ 40003e: 47e3 jrc ra
+
+#pass
diff --git a/ld/testsuite/ld-mips-elf/micromips-lineno.s b/ld/testsuite/ld-mips-elf/micromips-lineno.s
new file mode 100644
index 00000000000..0dced268360
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/micromips-lineno.s
@@ -0,0 +1,44 @@
+ # Dummy file name
+ .file 1 "micromips-lineno.c"
+ .section .text.foo,"ax",@progbits
+ .globl foo
+ .globl main
+ .globl start
+ .globl _start
+ .globl __start
+ # Dummy line number 1
+ .loc 1 1 0
+ .set micromips
+ .set nomips16
+ .ent foo
+foo:
+ nop
+ jr $ra
+ .end foo
+ .section .text.bar,"ax",@progbits
+ .globl bar
+ # Dummy line number 2
+ .loc 1 2 0
+ .set nomicromips
+ .ent bar
+bar:
+ nop
+ jr $ra
+ .end bar
+ .section .text.baz,"ax",@progbits
+ .globl baz
+ # Dummy line number 3
+ .loc 1 3 0
+ .set micromips
+ .ent baz
+baz:
+ nop
+ jr $ra
+ .end baz
+
+ .text
+main:
+start:
+_start:
+__start:
+ .byte 0
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 32a5cb8102f..5a9b422050a 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -312,6 +312,10 @@ if { $linux_gnu } {
# Check MIPS16 markings being passed through link.
run_dump_test "mips16-1"
+# Check if line numbers are correct for compressed functions.
+run_dump_test "mips16-lineno"
+run_dump_test "micromips-lineno"
+
# MIPS branch offset final link checking.
run_dump_test "branch-misc-1"
run_dump_test "branch-misc-2"
diff --git a/ld/testsuite/ld-mips-elf/mips16-lineno.d b/ld/testsuite/ld-mips-elf/mips16-lineno.d
new file mode 100644
index 00000000000..f07ce6cf2e1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-lineno.d
@@ -0,0 +1,31 @@
+#name: MIPS16 address mapping to debug line information
+#as: -march=mips2 -mabi=32
+#ld: -Ttext 0x400020
+#objdump: -dlr
+#source: mips16-lineno.s
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+
+00400020 <\_\_start>:
+ \.\.\.
+
+00400030 <foo>:
+foo\(\):
+ 400030: e820 jr ra
+.*mips16-lineno.c:1
+ 400032: 6500 nop
+
+00400034 <bar>:
+.*mips16-lineno.c:2
+ 400034: 03e00008 jr ra
+bar\(\):
+.*mips16-lineno.c:2
+ 400038: 00000000 nop
+
+0040003c <baz>:
+baz\(\):
+ 40003c: e820 jr ra
+.*mips16-lineno.c:3
+ 40003e: 6500 nop
diff --git a/ld/testsuite/ld-mips-elf/mips16-lineno.s b/ld/testsuite/ld-mips-elf/mips16-lineno.s
new file mode 100644
index 00000000000..48c2baa4948
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-lineno.s
@@ -0,0 +1,46 @@
+ # Dummy file name
+ .file 1 "mips16-lineno.c"
+ .section .text.foo,"ax",@progbits
+ .globl foo
+ .globl main
+ .globl start
+ .globl _start
+ .globl __start
+ # Dummy line number 1
+ .loc 1 1 0
+ .set mips16
+ .set nomicromips
+ .ent foo
+foo:
+ nop
+ jr $ra
+ .end foo
+ .section .text.bar,"ax",@progbits
+ .globl bar
+ # Dummy line number 2
+ .loc 1 2 0
+ .set nomips16
+ .ent bar
+bar:
+ nop
+ jr $ra
+ .end bar
+ .section .text.baz,"ax",@progbits
+ .globl baz
+ # Dummy line number 3
+ .loc 1 3 0
+ .set mips16
+ .ent baz
+baz:
+ nop
+ jr $ra
+ .end baz
+
+
+ .text
+main:
+start:
+_start:
+__start:
+ .byte 0
+
--
2.34.1
More information about the Binutils
mailing list