arch-generic: Fix reading from special :semihosting-features file

The implementation of SYS_FLEN was missing, which caused picolibc to
treat this file as not implemented. Additionally, there was a bug in
the SYS_READ call that was comparing the wrong variable against the
passed buffer length. It was comparing the current file position against
the buffer length instead of the number of written bytes.
Finally, pos was unititialized which could result in spurious errors.

Change-Id: I8b487a79df5970a5001d3fef08d5579bb4aa0dd0
This commit is contained in:
Alex Richardson
2024-04-30 16:00:03 -07:00
parent 666d1dd9a2
commit bb4c13143c
2 changed files with 14 additions and 5 deletions

View File

@@ -94,7 +94,7 @@ const std::map<uint64_t, const char *> BaseSemihosting::exitCodes{
{0x20029, "semi:ADP_Stopped_DivisionByZero"},
};
const std::vector<uint8_t> BaseSemihosting::features{
const std::array<uint8_t, 5> BaseSemihosting::features{
0x53, 0x48, 0x46, 0x42, // Magic
0x3, // EXT_EXIT_EXTENDED, EXT_STDOUT_STDERR
};
@@ -649,18 +649,26 @@ BaseSemihosting::FileBase::flen()
return -EINVAL;
}
static const std::vector<uint8_t> features;
BaseSemihosting::FileFeatures::
FileFeatures(BaseSemihosting &_parent, const char *_name, const char *_mode) :
FileBase(_parent, _name, _mode)
{}
int64_t
BaseSemihosting::FileFeatures::flen()
{
return features.size();
}
int64_t
BaseSemihosting::FileFeatures::read(uint8_t *buffer, uint64_t size)
{
int64_t len = 0;
for (; pos < size && pos < BaseSemihosting::features.size(); pos++)
buffer[len++] = BaseSemihosting::features[pos];
for (; len < size && pos < features.size(); pos++)
buffer[len++] = features[pos];
return len;
}

View File

@@ -323,9 +323,10 @@ class BaseSemihosting : public SimObject
int64_t read(uint8_t *buffer, uint64_t size) override;
int64_t seek(uint64_t pos) override;
int64_t flen() override;
protected:
size_t pos;
size_t pos = 0;
};
class File : public FileBase
@@ -540,7 +541,7 @@ class BaseSemihosting : public SimObject
static const std::vector<const char *> fmodes;
static const std::map<uint64_t, const char *> exitCodes;
static const std::vector<uint8_t> features;
static const std::array<uint8_t, 5> features;
static const std::map<const std::string, FILE *> stdioMap;
// used in callTmpNam() to deterministically generate a temp filename