ldscript_parser/
memory.rs

1use idents::symbol;
2use nom::{
3    branch::alt,
4    bytes::complete::{tag, take_until},
5    combinator::opt,
6    sequence::{delimited, tuple},
7    IResult,
8};
9use numbers::number;
10use whitespace::opt_space;
11
12#[derive(Debug, PartialEq)]
13pub struct Region {
14    pub name: String,
15    pub origin: u64,
16    pub length: u64,
17}
18
19fn attributes(input: &str) -> IResult<&str, &str> {
20    delimited(tag("("), take_until(")"), tag(")"))(input)
21}
22
23fn origin(input: &str) -> IResult<&str, &str> {
24    alt((tag("ORIGIN"), tag("org"), tag("o")))(input)
25}
26
27fn length(input: &str) -> IResult<&str, &str> {
28    alt((tag("LENGTH"), tag("len"), tag("l")))(input)
29}
30
31pub fn region(input: &str) -> IResult<&str, Region> {
32    let (input, name) = symbol(input)?;
33    let (input, _) = tuple((
34        opt_space,
35        opt(attributes),
36        wsc!(tag(":")),
37        origin,
38        wsc!(tag("=")),
39    ))(input)?;
40    let (input, org) = number(input)?;
41    let (input, _) = tuple((wsc!(tag(",")), length, wsc!(tag("="))))(input)?;
42    let (input, len) = number(input)?;
43    Ok((
44        input,
45        Region {
46            name: name.into(),
47            origin: org,
48            length: len,
49        },
50    ))
51}
52
53#[cfg(test)]
54mod tests {
55    use memory::*;
56
57    #[test]
58    fn test_region() {
59        assert_done!(
60            region("rom (rx)  : ORIGIN = 0, LENGTH = 256K"),
61            Region {
62                name: "rom".into(),
63                origin: 0,
64                length: 256 * 1024,
65            }
66        );
67        assert_done!(
68            region("ram (!rx) : org = 0x40000000, l = 4M"),
69            Region {
70                name: "ram".into(),
71                origin: 0x40000000,
72                length: 4 * 1024 * 1024,
73            }
74        );
75    }
76}