Skip to content

Commit

Permalink
read: Skip invalid ranges in RngListIter/LocListIter (#715)
Browse files Browse the repository at this point in the history
I've encountered a toolchain which produces invalid ranges, where the
end of the range is before the beginning.

I want to fix that toolchain, of course, but I also noticed that tools
like `llvm-addr2line` and `llvm-dwarfdump --lookup` apparently silently
skip the invalid ranges, so they're able to give partial answers. By
contrast, `gimli` returns an error in this case. Then the `addr2line`
crate, for example, bubbles the error all the way out and doesn't return
any results.

The specific toolchain where I've encountered this is TinyGo (which uses
LLVM), when building WebAssembly with the `wasip1` target. I tested
TinyGo 0.32.0-dev and LLVM 17, and this was the shortest program I could
find which produces invalid ranges:
tinygo build -target=wasip1 /tmp/test.go
```go
package main
import "os"
func main() {
        os.Lstat("some-filename")
}
```
  • Loading branch information
jameysharp committed May 24, 2024
1 parent 0fe475c commit e095972
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 21 deletions.
11 changes: 3 additions & 8 deletions src/read/loclists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,15 +650,10 @@ impl<R: Reader> LocListIter<R> {
}
};

if range.begin == tombstone {
if range.begin == tombstone || range.begin > range.end {
return Ok(None);
}

if range.begin > range.end {
self.raw.input.empty();
return Err(Error::InvalidLocationAddressRange);
}

Ok(Some(LocationListEntry { range, data }))
}
}
Expand Down Expand Up @@ -1522,7 +1517,7 @@ mod tests {
debug_addr_base,
)
.unwrap();
assert_eq!(locations.next(), Err(Error::InvalidLocationAddressRange));
assert_eq!(locations.next(), Ok(None));

// An invalid location range after wrapping.
let mut locations = loclists
Expand All @@ -1534,7 +1529,7 @@ mod tests {
debug_addr_base,
)
.unwrap();
assert_eq!(locations.next(), Err(Error::InvalidLocationAddressRange));
assert_eq!(locations.next(), Ok(None));

// An invalid offset.
match loclists.locations(
Expand Down
5 changes: 0 additions & 5 deletions src/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,8 +386,6 @@ pub enum Error {
UnknownCallFrameInstruction(constants::DwCfa),
/// The end of an address range was before the beginning.
InvalidAddressRange,
/// The end offset of a loc list entry was before the beginning.
InvalidLocationAddressRange,
/// Encountered a call frame instruction in a context in which it is not
/// valid.
CfiInstructionInInvalidContext,
Expand Down Expand Up @@ -547,9 +545,6 @@ impl Error {
Error::InvalidAddressRange => {
"The end of an address range must not be before the beginning."
}
Error::InvalidLocationAddressRange => {
"The end offset of a location list entry must not be before the beginning."
}
Error::CfiInstructionInInvalidContext => {
"Encountered a call frame instruction in a context in which it is not valid."
}
Expand Down
11 changes: 3 additions & 8 deletions src/read/rnglists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,15 +569,10 @@ impl<R: Reader> RngListIter<R> {
}
};

if range.begin == tombstone {
if range.begin == tombstone || range.begin > range.end {
return Ok(None);
}

if range.begin > range.end {
self.raw.input.empty();
return Err(Error::InvalidAddressRange);
}

Ok(Some(range))
}
}
Expand Down Expand Up @@ -1402,7 +1397,7 @@ mod tests {
debug_addr_base,
)
.unwrap();
assert_eq!(ranges.next(), Err(Error::InvalidAddressRange));
assert_eq!(ranges.next(), Ok(None));

// An invalid range after wrapping.
let mut ranges = rnglists
Expand All @@ -1414,7 +1409,7 @@ mod tests {
debug_addr_base,
)
.unwrap();
assert_eq!(ranges.next(), Err(Error::InvalidAddressRange));
assert_eq!(ranges.next(), Ok(None));

// An invalid offset.
match rnglists.ranges(
Expand Down

0 comments on commit e095972

Please sign in to comment.